/**
 * Copyright 2014  XCL-Charts
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @Project XCL-Charts
 * @Description Android图表基类库
 * @author XiongChuanLiang<br></br>(xcl_168@aliyun.com)
 * @Copyright Copyright (c) 2014 XCL-Charts (www.xclcharts.com)
 * @license http://www.apache.org/licenses/  Apache v2 License
 * @version 1.0
 */
package com.demo.xclcharts.view1

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import com.gitee.wsl.common.chart.ChartEnum
import com.gitee.wsl.common.chart.model.PlotDot
import com.gitee.wsl.common.chart.render.foreground.CustomLineData
import com.gitee.wsl.common.chart.render.foreground.info.Anchor
import com.gitee.wsl.common.chart.sample.bar.BarChart
import com.gitee.wsl.common.chart.sample.bar.model.BarData
import com.gitee.wsl.common.chart.sample.pie.PieChart
import com.gitee.wsl.common.chart.sample.pie.model.PieData
import com.gitee.wsl.common.ui.draw.type.DotStyle
import com.gitee.wsl.common.ui.draw.type.GridDirection
import com.gitee.wsl.common.ui.draw.type.LineSpacingStyle
import org.xclcharts.common.DensityUtil

import java.text.DecimalFormat

/**
 * @ClassName BarChart01View
 * @Description  柱形图例子(竖向)
 *
 * @author XiongChuanLiang<br></br>(xcl_168@aliyun.com)
 */
class BarChart01View : DemoView, Runnable {
    //DemoView
    private val TAG = "BarChart01View"
    private val chart = BarChart()

    //标签轴
    private val chartLabels: MutableList<String> = ArrayList()
    private val chartData: MutableList<BarData> = ArrayList()
    var mPaintToolTip = Paint(Paint.ANTI_ALIAS_FLAG)
    var mDotToolTip = PlotDot()
    private val mCustomLineDataset: MutableList<CustomLineData> = ArrayList()
    private val colorORACLE = Color.rgb(186, 20, 26)
    private val colorMSSQL = Color.rgb(1, 188, 242)
    private val colorMYSQL = Color.rgb(0, 75, 106)
    private val colorOTHER = Color.rgb(27, 188, 155)
    private val colorTitalAxes = Color.rgb(244, 109, 67)
    private val colorPlotArea = Color.rgb(254, 224, 144)
    private val chartPie = PieChart()
    private val chartDataPie = ArrayList<PieData>()

    constructor(context: Context) : super(context) {
        // TODO Auto-generated constructor stub
        initView()
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        initView()
    }

    constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(
        context,
        attrs,
        defStyle
    ) {
        initView()
    }

    private fun initView() {
        chartLabels()
        chartDataSet()
        chartRender()

        //饼图
        chartPieDataSet()
        chartPieRender()

        //綁定手势滑动事件
        this.bindTouch(this, chart)
        this.bindTouch(this, chartPie)
        Thread(this).start()
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        //图所占范围大小
        //chart.setChartRange(w.toFloat(), h.toFloat()) // + w * 0.5f
    }

    private fun chartRender() {
        try {
            //设置绘图区默认缩进px值,留置空间显示Axis,Axistitle....		
            val ltrb = barLnDefaultSpadding
            /*chart.setPadding(
                ltrb[0].toFloat(),
                ltrb[1].toFloat(),
                ltrb[2].toFloat(),
                ltrb[3].toFloat()
            )*/

            //数据源
            chart.dataSet = chartData
            chart.setCategories(chartLabels)

            //轴标题
            chart.axisTitle?.leftTitle = "数据库"
            chart.axisTitle?.lowerTitle = "分布位置"

            //数据轴
            chart.dataAxis.axisMax=100.0f
            chart.dataAxis.axisMin=0.0f
            chart.dataAxis.axisSteps = 5.0f

            //定义数据轴标签显示格式
            chart.dataAxis.labelFormatter= { value -> // TODO Auto-generated method stub
                val tmp = value.toDouble()
                val df = DecimalFormat("#0")
                val label = df.format(tmp).toString()
                label
            }

            //在柱形顶部显示值
            chart.flatBar.isShowItemLabel=true


            //设定格式
            chart.itemLabelFormatter= { value -> // TODO Auto-generated method stub
                val df = DecimalFormat("#0")
                df.format(value).toString()
            }

            //让柱子间没空白
            //chart.getBar().setBarInnerMargin(0d);


            //轴颜色			
            chart.dataAxis.axisPaint.color = colorTitalAxes
            chart.categoryAxis.axisPaint.color = colorTitalAxes
            chart.dataAxis.tickMarkPaint.color = colorTitalAxes
            chart.categoryAxis.tickMarkPaint.color = colorTitalAxes
            chart.dataAxis.tickLabelPaint.color = colorTitalAxes
            chart.categoryAxis.tickLabelPaint.color = colorTitalAxes
            chart.axisTitle?.leftTitlePaint?.color = colorTitalAxes
            chart.axisTitle?.lowerTitlePaint?.color = colorTitalAxes
            chart.flatBar.itemLabelPaint.color = Color.rgb(246, 133, 39)
            chart.flatBar.itemLabelPaint.textSize = 15f


            //指隔多少个轴刻度(即细刻度)后为主刻度
            chart.dataAxis.detailModeSteps = 5.0f

            //显示十字交叉线
            chart.showCrossLine()
             chart.crossLine?.let{
                 it.dyLineStyle = ChartEnum.DyLineStyle.Horizontal
                 it.lineDrawStyle = LineSpacingStyle.Dash
            }
            

            //数据轴居中显示
            //chart.setDataAxisLocation(ChartEnum.AxisLocation.VERTICAL_CENTER);

            //忽略Java的float计算误差，提高性能
            //chart.disableHighPrecision();

            //柱形和标签居中方式
            // chart.setBarCenterStyle(ChartEnum.BarCenterStyle.TICKMARKS);
        } catch (e: Exception) {
            // TODO Auto-generated catch block
            Log.e(TAG, "chartRender():$e")
        }
    }

    private fun chartDataSet() {
        //标签对应的柱形数据集
        val dataSeriesA: MutableList<Float> = ArrayList()
        dataSeriesA.add(66.0f)
        dataSeriesA.add(33.0f)
        dataSeriesA.add(50.0f)
        val BarDataA = BarData("Oracle", dataSeriesA, colorORACLE)
        val dataSeriesB: MutableList<Float> = ArrayList()
        dataSeriesB.add(0.0f) //32
        dataSeriesB.add(25.0f)
        dataSeriesB.add(18.0f)
        val BarDataB = BarData("SQL Server", dataSeriesB, colorMSSQL)
        val dataSeriesC: MutableList<Float> = ArrayList()
        dataSeriesC.add(79.0f)
        dataSeriesC.add(91.0f)
        dataSeriesC.add(65.0f)
        val BarDataC = BarData("MySQL", dataSeriesC, colorMYSQL)
        val dataSeriesD: MutableList<Float> = ArrayList()
        dataSeriesD.add(52.0f)
        dataSeriesD.add(45.0f)
        dataSeriesD.add(35.0f)
        val BarDataD = BarData("其它类型", dataSeriesD, colorOTHER)
        chartData.add(BarDataA)
        chartData.add(BarDataB)
        chartData.add(BarDataC)
        chartData.add(BarDataD)
    }

    private fun chartLabels() {
        chartLabels.add("福田数据中心")
        chartLabels.add("西丽数据中心")
        chartLabels.add("观澜数据中心")
    }

    override fun render(canvas: Canvas) {
        try {
            chart.render(canvas)
            chartPie.render(canvas)
        } catch (e: Exception) {
            Log.e(TAG, e.toString())
        }
    }

    override fun run() {
        // TODO Auto-generated method stub
        try {
            chartAnimation()
        } catch (e: Exception) {
            Thread.currentThread().interrupt()
        }
    }

    private fun chartAnimation() {
        try {
            chart.dataAxis.hide()
            chart.plotLegend.hide()
            val ltrb = barLnDefaultSpadding
            for (i in 8 downTo 1) {
                Thread.sleep(100)
               /* chart.setPadding(
                    ltrb[0].toFloat(),
                    (i * ltrb[1]).toFloat(),
                    ltrb[2].toFloat(),
                    ltrb[3].toFloat()
                )*/
                if (1 == i) {
                    drawLast()
                    drawDyLegend()
                }
                postInvalidate()
            }
        } catch (e: Exception) {
            Thread.currentThread().interrupt()
        }
    }

    private fun drawLast() {
        //标题
        chart.setTitle("数据库统计","(XCL-Charts Demo)")
        chart.plotTitle.titlePaint.color = colorTitalAxes
        chart.plotTitle.subtitlePaint.color = colorTitalAxes

        //激活点击监听
        //chart.ableSelect()
        //chart.showClikedFocus()

        //扩展横向显示范围,当数据太多时可用这个扩展实际绘图面积
        //chart.getPlotArea().extWidth(200f);		

        //禁用平移模式
        //chart.disablePanMode()
        //限制只能左右滑动
        //chart.setPlotPanMode(ChartEnum.PanMode.HORIZONTAL);	

        //禁用双指缩放
        //chart.disableScale();
        chart.dataAxis.show()
        chart.plotLegend.show()

        //当值与轴最小值相等时，不显示轴
        chart.isEqualAxisMin=false

        //批注
        val mAnchorSet: MutableList<Anchor> = ArrayList()
        val an1 = Anchor(2, 0, ChartEnum.AnchorStyle.CIRCLE)
        an1.alpha = 200
        an1.bgColor = Color.rgb(203, 189, 231)
        //an1.setAreaStyle(ChartEnum.DataAreaStyle.FILL);
        val an2 = Anchor(1, 1, ChartEnum.AnchorStyle.CIRCLE) //CIRCLE
        an2.bgColor = Color.GRAY
        val an3 = Anchor(0, 2, ChartEnum.AnchorStyle.RECT) //CAPROUNDRECT  RECT
        an3.bgColor = Color.rgb(255, 145, 126)
        val an4 = Anchor(0, 1, ChartEnum.AnchorStyle.CAPRECT)
        an4.bgColor = Color.rgb(255, 145, 126)
        an4.anchor = "我是批注"
        mAnchorSet.add(an1)
        mAnchorSet.add(an2)
        mAnchorSet.add(an3)
        mAnchorSet.add(an4)
        chart.anchorSet = mAnchorSet
        chart.isShowBackground=true
        chart.setBackgroundColor(
            GridDirection.VERTICAL,
            Color.rgb(69, 117, 180),
            Color.rgb(224, 243, 248)
        ) //Color.rgb(17, 162, 255),Color.rgb(163, 219, 254));//Color.WHITE);				
        chart.borderReader.backgroundColor=Color.rgb(181, 64, 1)
        chart.borderReader.linePaint.strokeWidth = 3f
        chart.plotViewport.setBackgroundColor(true, colorPlotArea)

        //chart.getPlotArea().setApplayGradient(true);
        //chart.getPlotArea().setGradientDirection(ChartEnum.Direction.VERTICAL);
        //chart.getPlotArea().setBeginColor(Color.rgb(116, 174, 210)); 		
        //chart.getPlotArea().setEndColor(Color.WHITE);
        chart.showRoundBorder()
        val line1 = CustomLineData("分界", 60.0f, Color.rgb(218, 198, 61), 7)
        line1.customeLineCap= DotStyle.HIDE
        line1.labelHorizontalPostion = Paint.Align.RIGHT
        //line1.setLabelOffset(15);	
        line1.lineLabelPaint.color = Color.RED
        mCustomLineDataset.add(line1)
        chart.customLine.customLineDataset = mCustomLineDataset


        //饼图 
        val pieWH = DensityUtil.dip2px(context, 70f).toFloat()
        val pieX = chart.plotViewport.right - pieWH * 3
        chartPie.setChartRange(pieX, pieWH, pieWH, pieWH)
    }

    private fun drawDyLegend() {
       /* val dyLegend = chart.crossLine ?: return
        dyLegend.setPosition(0.8f, 0.5f)
        if (chart.plotArea.height > chart.plotArea.width) {
            dyLegend.setPosition(0.6f, 0.5f)
        }
        //dyLegend.setColSpan(30.f);
        dyLegend.backgroundPaint.color = Color.BLACK
        dyLegend.backgroundPaint.alpha = 100
        dyLegend.setRowSpan(20f)
        dyLegend.setMargin(15f)
        dyLegend.setStyle(ChartEnum.DyInfoStyle.ROUNDRECT)
        val pDyLegend = Paint(Paint.ANTI_ALIAS_FLAG)
        pDyLegend.color = Color.GREEN
        val dotDyLegend = PlotDot()
        dotDyLegend.dotStyle = ChartEnum.DotStyle.RECT
        dyLegend.addLegend(dotDyLegend, "库可用xxx(PB)", pDyLegend)
        val pDyLegend2 = Paint(Paint.ANTI_ALIAS_FLAG)
        pDyLegend2.color = Color.RED
        dyLegend.addLegend(dotDyLegend, "库已用xxx(PB)", pDyLegend2)
        val pDyLegend3 = Paint(Paint.ANTI_ALIAS_FLAG)
        pDyLegend3.color = Color.CYAN
        dyLegend.addLegend(dotDyLegend, "未分配xxx(PB)", pDyLegend3)
        val pDyLegend4 = Paint(Paint.ANTI_ALIAS_FLAG)
        pDyLegend4.color = Color.YELLOW
        dyLegend.addLegend("总计:xxx(PB)", pDyLegend4)*/
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        // TODO Auto-generated method stub		
        super.onTouchEvent(event)
        if (event.action == MotionEvent.ACTION_UP) {
            triggerClick(event.x, event.y)
        }
        return true
    }

    //触发监听
    private fun triggerClick(x: Float, y: Float) {

        val crossLine = chart.crossLine
        //交叉线
         chart.crossLine?.setCurrentXY(x, y)
        if (chart.crossLine!=null) {
            //交叉线
            if ( chart.crossLine!!.isInvalidate) this.invalidate()
        } else {
            val record = chart.getPositionRecord(x, y)
            if (null == record) {
                if (chart.crossLine!=null) this.invalidate()
                return
            }
            if (record.dataID >= chartData.size) return
            val bData = chartData[record.dataID]
            if (record.dataChildID >= bData.dataSet.size) return
            val bValue = bData.dataSet[record.dataChildID]

            //显示选中框
            record.rectF?.let { chart.showFocusRectF(it) }
            chart.focusPaint.style = Paint.Style.STROKE
            chart.focusPaint.strokeWidth = 3f
            chart.focusPaint.color = Color.GREEN


            //在点击处显示tooltip
            mPaintToolTip.isAntiAlias = true
            mPaintToolTip.color = bData.color
            mDotToolTip.dotStyle = DotStyle.RECT
            mDotToolTip.color = Color.BLUE //bData.getColor());

            //位置显示方法一:
            //用下列方法可以让tooltip显示在柱形顶部
            //chart.getToolTip().setCurrentXY(record.getRectF().centerX(),record.getRectF().top);
            //位置显示方法二:
            //用下列方法可以让tooltip在所点击位置显示
            chart.toolTip?.setCurrentXY(x, y)
            chart.toolTip?.style=ChartEnum.DyInfoStyle.ROUNDRECT
            chart.toolTip?.addToolTip(mDotToolTip, bData.key, mPaintToolTip)
            chart.toolTip?.addToolTip(
                "数量:" + java.lang.Float.toString(bValue), mPaintToolTip
            )
            chart.toolTip?.backgroundPaint?.alpha = 100
            chart.toolTip?.setAlign(Paint.Align.CENTER)
            chart.toolTip?.style=ChartEnum.DyInfoStyle.CIRCLE
            //chart.getToolTip().getBackgroundPaint().setColor(Color.rgb(30, 30, 30));
            this.invalidate()
        }
    }

    private fun chartPieRender() {
        try {
            //标签显示(隐藏，显示在中间，显示在扇区外面)
            chartPie.labelStyle = ChartEnum.SliceLabelStyle.INSIDE
            chartPie.labelPaint.color = Color.WHITE
            chartPie.dataSet = chartDataPie
            chartPie.plotLegend.hide()
        } catch (e: Exception) {
            // TODO Auto-generated catch block
            Log.e(TAG, "chartPieRender():$e")
        }
    }

    private fun chartPieDataSet() {
        //演示用，不精准计算，生产环境应使用MathHelper相关类来时行计算				
        //随便弄的
        chartDataPie.clear()
        chartDataPie.add(PieData("ORACLE", "27%", 27.0f, colorORACLE))
        chartDataPie.add(PieData("SQL Server", "8%", 8.0f, colorMSSQL))
        chartDataPie.add(PieData("MySQL", "42%", 42.0f, colorMYSQL))
        chartDataPie.add(PieData("其它", "23%", 23.0f, colorOTHER))
    }
}